import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.table.JTableHeader;

import jdk.nashorn.internal.scripts.JS;
import table.DTable;
import table.GroupHeader;
import table.TableContent;
import table.DTableUI;



public class TestMain {
	public static void main(String[] args) throws IOException {
		JTable table = createTable();
		table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

		BufferedImage image = createImage(table);
		BufferedImage imageWithOutJFrame = createImageWithOutJFrame(table);
		//有jframe生成图片
		ImageIO.write(image, "png", new File("D:\\test\\table\\bin\\image.png"));
		//无jframe生成图片
		ImageIO.write(imageWithOutJFrame, "png", new File("D:\\test\\table\\bin\\image-no-jfrmae.png"));
	}


	public static BufferedImage createImage(JTable table) {
		JFrame frame = new JFrame();
		frame.setSize(0, 0);
		frame.setLayout(new GridBagLayout());
		frame.add(new JScrollPane(table),new GBC(0,0).setWeight(100,100).setFill(GBC.BOTH));
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.pack();
        // get the table header component
        JTableHeader tableHeaderComp = table.getTableHeader();
        int totalWidth = table.getPreferredSize().width;
        int totalHeight = table.getPreferredSize().height;
        BufferedImage tableImage = new BufferedImage(totalWidth, totalHeight+tableHeaderComp.getPreferredSize().height, BufferedImage.TYPE_INT_ARGB);

        Graphics2D g2D = (Graphics2D) tableImage.createGraphics();

        table.setBackground(Color.BLUE);

        g2D.setColor(Color.WHITE);
        g2D.fillRect(0, 0, totalWidth, totalHeight);

        g2D.translate(0, 0);
        tableHeaderComp.paint(g2D);

        g2D.translate(0, tableHeaderComp.getPreferredSize().height);
		table.paint(g2D);

        g2D.dispose();
		frame.dispose();

        //return the table image
        return tableImage;    
    }


	public static BufferedImage createImageWithOutJFrame(JTable table) {
		// get the table header component
		JTableHeader tableHeaderComp = table.getTableHeader();
		int totalWidth = table.getPreferredSize().width;
		int totalHeight = table.getPreferredSize().height;
		BufferedImage tableImage = new BufferedImage(totalWidth, totalHeight+tableHeaderComp.getPreferredSize().height, BufferedImage.TYPE_INT_ARGB);
		Graphics2D g2D = (Graphics2D) tableImage.createGraphics();
		table.setBackground(Color.BLUE);
		JPanel jPanel = new JPanel();
		SwingUtilities.paintComponent(g2D,tableHeaderComp,jPanel,0,0,tableImage.getWidth(),tableImage.getHeight());
		SwingUtilities.paintComponent(g2D,table,jPanel,0,tableHeaderComp.getPreferredSize().height,tableImage.getWidth(),tableImage.getHeight());
		g2D.dispose();

		//return the table image
		return tableImage;
	}


	public static JTable createTable() {
		TableContent tableContent = new TableContent();
		tableContent.append("测试项目1", 1, 8);
		tableContent.append("测试", 1, 2);
		tableContent.append("数量");
		tableContent.println();
		tableContent.append("比率");
		tableContent.println();
		tableContent.append("编码", 1, 2);
		tableContent.append("数量");
		tableContent.append("跨多行多列",3,4);
		tableContent.println();
		tableContent.append("比率");
		tableContent.println();
		tableContent.append("设计", 1, 2);
		tableContent.append("数量");
		tableContent.println();
		tableContent.append("比率");
		tableContent.println();
		tableContent.append("需求", 1, 2);
		tableContent.append("数量");
		tableContent.println();
		tableContent.append("比率");
		tableContent.println();
		List<GroupHeader> list=new ArrayList<GroupHeader>();
		list.add(new GroupHeader("BUG类型",3,7));
		list.add(new GroupHeader("阶段",1,2));
		return DTable.create(tableContent
				,new Object[]{"被测试项目",GroupHeader.EMPTY_LABEL,GroupHeader.EMPTY_LABEL,"逻辑错误","文本错误","接口错误","程序错误","合计"}
				,list);
		
	}
	
}

/**
 * 该类来自于《Java核心技术》
 * @author Administrator
 *
 */
class GBC extends GridBagConstraints {
	/**
	 Constructs a GBC with a given gridx and gridy position and
	 all other grid bag constraint values set to the default.
	 @param gridx the gridx position
	 @param gridy the gridy position
	 */
	public GBC(int gridx, int gridy) {
		this.gridx = gridx;
		this.gridy = gridy;
	}

	/**
	 Constructs a GBC with given gridx, gridy, gridwidth, gridheight
	 and all other grid bag constraint values set to the default.
	 @param gridx the gridx position
	 @param gridy the gridy position
	 @param gridwidth the cell span in x-direction
	 @param gridheight the cell span in y-direction
	 */
	public GBC(int gridx, int gridy, int gridwidth, int gridheight) {
		this.gridx = gridx;
		this.gridy = gridy;
		this.gridwidth = gridwidth;
		this.gridheight = gridheight;
	}

	/**
	 Sets the anchor.
	 @param anchor the anchor value
	 @return this object for further modification
	 */
	public GBC setAnchor(int anchor) {
		this.anchor = anchor;
		return this;
	}

	/**
	 Sets the fill direction.
	 @param fill the fill direction
	 @return this object for further modification
	 */
	public GBC setFill(int fill) {
		this.fill = fill;
		return this;
	}

	/**
	 Sets the cell weights.
	 @param weightx the cell weight in x-direction
	 @param weighty the cell weight in y-direction
	 @return this object for further modification
	 */
	public GBC setWeight(double weightx, double weighty) {
		//super.w
		this.weightx = weightx;
		this.weighty = weighty;
		return this;
	}

	/**
	 Sets the insets of this cell.
	 @param distance the spacing to use in all directions
	 @return this object for further modification
	 */
	public GBC setInsets(int distance) {
		this.insets = new Insets(distance, distance, distance, distance);
		return this;
	}

	/**
	 Sets the insets of this cell.
	 @param top the spacing to use on top
	 @param left the spacing to use to the left
	 @param bottom the spacing to use on the bottom
	 @param right the spacing to use to the right
	 @return this object for further modification
	 */
	public GBC setInsets(int top, int left, int bottom, int right) {
		this.insets = new Insets(top, left, bottom, right);
		return this;
	}

	/**
	 Sets the internal padding
	 @param ipadx the internal padding in x-direction
	 @param ipady the internal padding in y-direction
	 @return this object for further modification
	 */
	public GBC setIpad(int ipadx, int ipady) {
		this.ipadx = ipadx;
		this.ipady = ipady;
		return this;
	}
}
